package com.itfreer.gis.shape.analysis;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.springframework.stereotype.Component;

import com.itfreer.gis.analysis.IGisFileAnalysis;
import com.itfreer.gis.graphic.GisGraphic;
import com.itfreer.gis.graphic.GisLine;
import com.itfreer.gis.graphic.GisPoint;
import com.itfreer.gis.graphic.GisPolyg;

import java.util.Set;

import gov.nasa.worldwind.exception.WWRuntimeException;
import gov.nasa.worldwind.exception.WWUnrecognizedException;
import gov.nasa.worldwind.formats.shapefile.DBaseField;
import gov.nasa.worldwind.formats.shapefile.DBaseFile;
import gov.nasa.worldwind.formats.shapefile.DBaseRecord;
import gov.nasa.worldwind.formats.shapefile.Shapefile;
import gov.nasa.worldwind.formats.shapefile.ShapefilePolygons;
import gov.nasa.worldwind.formats.shapefile.ShapefileRecord;
import gov.nasa.worldwind.formats.shapefile.ShapefileRecordPolygon;
import gov.nasa.worldwind.formats.shapefile.ShapefileRenderable;
import gov.nasa.worldwind.formats.shapefile.ShapefileUtils;
import gov.nasa.worldwind.geom.LatLon;
import gov.nasa.worldwind.geom.Position;
import gov.nasa.worldwind.layers.Layer;
import gov.nasa.worldwind.render.airspaces.Polygon;
import gov.nasa.worldwind.util.Logging;
import gov.nasa.worldwind.util.VecBuffer;
import gov.nasa.worldwind.util.WWIO;
import gov.nasa.worldwindx.examples.util.ShapefileLoader;
@Component("shape")
public class ShapeAnalysis implements IGisFileAnalysis {
	
    protected static final String SHAPE_FILE_SUFFIX = ".shp";
    protected static final String INDEX_FILE_SUFFIX = ".shx";
    protected static final String ATTRIBUTE_FILE_SUFFIX = ".dbf";
    protected static final String PROJECTION_FILE_SUFFIX = ".prj";

	/**
	 * zip文件解压到shape文件
	 * @param zipFileName
	 * @return
	 */
	public static Shapefile zipFileReader(String zipFileName) {
		File file=new File(zipFileName);
        InputStream shpStream = null, shxStream = null, dbfStream = null, prjStream = null;

        ZipFile zipFile;
        try
        {
            zipFile = new ZipFile(file);
            Enumeration<? extends ZipEntry> zipEntries = zipFile.entries();

            while (zipEntries.hasMoreElements())
            {
                ZipEntry entry = zipEntries.nextElement();
                if (entry == null)
                    continue;

                if (entry.getName().toLowerCase().endsWith(ShapeAnalysis.SHAPE_FILE_SUFFIX))
                {
                    shpStream = zipFile.getInputStream(entry);
                }
                else if (entry.getName().toLowerCase().endsWith(ShapeAnalysis.INDEX_FILE_SUFFIX))
                {
                    shxStream = zipFile.getInputStream(entry);
                }
                else if (entry.getName().toLowerCase().endsWith(ShapeAnalysis.ATTRIBUTE_FILE_SUFFIX))
                {
                    dbfStream = zipFile.getInputStream(entry);
                }
                else if (entry.getName().toLowerCase().endsWith(ShapeAnalysis.PROJECTION_FILE_SUFFIX))
                {
                    prjStream = zipFile.getInputStream(entry);
                }
            }
        }
        catch (Exception e)
        {
            throw new WWRuntimeException(
                Logging.getMessage("generic.ExceptionAttemptingToReadFrom", file.getPath()), e);
        }

        if (shpStream == null)
        {
            String message = Logging.getMessage("SHP.UnrecognizedShapefile", file.getPath());
            Logging.logger().severe(message);
            throw new WWUnrecognizedException(message);
        }

        return new Shapefile(shpStream, shxStream, dbfStream);
	}
	
	/**
	 * 解析shape文件
	 * @throws FileNotFoundException
	 */
	@Override
    public List<GisGraphic> analysis(String zipFileName) throws Exception  
    {  
/*        String shpFilePath = "D:\\CAD文件\\shape\\polyg.shp";  
        String shxFilePath = "D:\\CAD文件\\shape\\polyg.shx";  
        String dbfFilePath = "D:\\CAD文件\\shape\\polyg.dbf";  
        String prjFilePath = "D:\\CAD文件\\shape\\polyg.prj";  
  
        InputStream shpInputStream = new FileInputStream(shpFilePath);  
        InputStream shxInputStream = new FileInputStream(shxFilePath);  
        InputStream dbfInputStream = new FileInputStream(dbfFilePath);  
        InputStream prjInputStream = new FileInputStream(prjFilePath);  
  
        // 实例化一个shapefile类  
        Shapefile shapefile = new Shapefile(shpInputStream, shxInputStream,  
                dbfInputStream);*/
    	List<GisGraphic> resultLst=new ArrayList<GisGraphic>();
    	Shapefile shapefile =ShapeAnalysis.zipFileReader(zipFileName);
        if(shapefile!=null) {
        	Set<String> names=shapefile.getAttributeNames();
        	while(shapefile.hasNext()) {
        		 //1、解析图形坐标
        		 ShapefileRecord record = shapefile.nextRecord();
        		 VecBuffer vb = record.getPointBuffer(0); 
        		 Iterable<LatLon> latLon= vb.getLocations();
        		 GisGraphic graphic=null;
        		 Iterator<LatLon> iterator=latLon.iterator();
        		 if(Shapefile.isPointType(shapefile.getShapeType())) {
        			 graphic=new GisPoint();
        			 while(iterator.hasNext()) {
             			
            			 LatLon l=iterator.next();
            			 Double y=Double.parseDouble(l.latitude.toString().replace("°", ""));
            			 Double x=Double.parseDouble(l.longitude.toString().replace("°", ""));
            			 ((GisPoint)graphic).setX(x);
            			 ((GisPoint)graphic).setX(y);
            		 }
    			 }else if(Shapefile.isPolygonType(shapefile.getShapeType())) {
    				 graphic=new GisPolyg();
        			 while(iterator.hasNext()) {
             			
            			 LatLon l=iterator.next();
            			 Double y=Double.parseDouble(l.latitude.toString().replace("°", ""));
            			 Double x=Double.parseDouble(l.longitude.toString().replace("°", ""));
            			 
            			 GisPoint point=new GisPoint();
            			 point.setX(x);
            			 point.setY(y);
            			 ((GisPolyg)graphic).addPoint(point);
            		 }
    			 }else if(Shapefile.isPolylineType(shapefile.getShapeType())) {
    				 graphic=new GisLine();
        			 while(iterator.hasNext()) {
             			
            			 LatLon l=iterator.next();
            			 Double y=Double.parseDouble(l.latitude.toString().replace("°", ""));
            			 Double x=Double.parseDouble(l.longitude.toString().replace("°", ""));
            			 
            			 GisPoint point=new GisPoint();
            			 point.setX(x);
            			 point.setY(y);
            			 ((GisLine)graphic).addPoint(point);
            		 }
    			 }
        		
        		 //2、解析属性信息
        		 HashMap<String,Object> attribute=new HashMap<String,Object>();
        		 if(names!=null && names.size()>0) {
        			 DBaseRecord dBaseRecord = record.getAttributes();
        			 for(String iName:names) {
        				 attribute.put(iName,dBaseRecord.getValue(iName));
        			 }
        		 }
        		 graphic.setAttribute(attribute);
    			 graphic.setGeometry();
    			 resultLst.add(graphic);
        	}
        }
        return resultLst;
    }
}
